package com.xlh.enums.course;

import com.google.common.collect.Lists;
import com.xlh.enums.ResourcesTypeEnum;
import com.xlh.enums.user.IdentityEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 章节类型
 * <p>
 * Created by lx on 2019/1/28.
 */
@Getter
@AllArgsConstructor
public enum ChapterTypeEnum {

    THEORY(1, "理论课") {
        @Override
        public List<ChapterResourceViewEnum> getChapterResourceView(IdentityEnum identityEnum) {
            List<ChapterResourceViewEnum> data = Lists.newArrayList(ChapterResourceViewEnum.THEORY,
                    ChapterResourceViewEnum.PREPARATION_MATERIALS, ChapterResourceViewEnum.RESOURCE,
                    ChapterResourceViewEnum.PRACTICE);
            if (identityEnum == IdentityEnum.STUDENT) {
                data.remove(ChapterResourceViewEnum.PREPARATION_MATERIALS);
            }
            return data;
        }

        @Override
        public List<ResourcesTypeEnum> getResourceType() {
            return Lists.newArrayList(ResourcesTypeEnum.THEORY_VIDEO, ResourcesTypeEnum.COURSEWARE,
                    ResourcesTypeEnum.PRACTICE, ResourcesTypeEnum.PREPARATION_MATERIALS,
                    ResourcesTypeEnum.LEARNING_RESOURCES, ResourcesTypeEnum.OTHER_RESOURCES);
        }
    },
    EXPERIMENT(2, "实验课") {
        @Override
        public List<ChapterResourceViewEnum> getChapterResourceView(IdentityEnum identityEnum) {
            return Lists.newArrayList(ChapterResourceViewEnum.EXPERIMENT, ChapterResourceViewEnum.RESOURCE);
        }

        @Override
        public List<ResourcesTypeEnum> getResourceType() {
            return Lists.newArrayList(ResourcesTypeEnum.EXPERIMENT_VIDEO, ResourcesTypeEnum.LABORATORY_MANUAL,
                    ResourcesTypeEnum.LEARNING_RESOURCES, ResourcesTypeEnum.OTHER_RESOURCES, ResourcesTypeEnum.LABORATORY_TARGET);
        }
    },
    THEORY_EXPERIMENT(3, "理论及单任务实验课") {
        @Override
        public List<ChapterResourceViewEnum> getChapterResourceView(IdentityEnum identityEnum) {
            List<ChapterResourceViewEnum> data = Lists.newArrayList(ChapterResourceViewEnum.THEORY,
                    ChapterResourceViewEnum.EXPERIMENT, ChapterResourceViewEnum.PREPARATION_MATERIALS,
                    ChapterResourceViewEnum.RESOURCE, ChapterResourceViewEnum.PRACTICE);
            if (identityEnum == IdentityEnum.STUDENT) {
                data.remove(ChapterResourceViewEnum.PREPARATION_MATERIALS);
            }
            return data;
        }

        @Override
        public List<ResourcesTypeEnum> getResourceType() {
            List<ResourcesTypeEnum> resourcesTypeEnums = ChapterTypeEnum.THEORY.getResourceType();
            resourcesTypeEnums.addAll(ChapterTypeEnum.EXPERIMENT.getResourceType());
            return resourcesTypeEnums.stream().distinct().collect(Collectors.toList());
        }
    },
    THEORY_MANY_EXPERIMENT(4, "理论及多任务实验课") {
        @Override
        public List<ChapterResourceViewEnum> getChapterResourceView(IdentityEnum identityEnum) {
            List<ChapterResourceViewEnum> data = Lists.newArrayList(ChapterResourceViewEnum.THEORY,
                    ChapterResourceViewEnum.EXPERIMENT, ChapterResourceViewEnum.PREPARATION_MATERIALS,
                    ChapterResourceViewEnum.RESOURCE, ChapterResourceViewEnum.PRACTICE);
            if (identityEnum == IdentityEnum.STUDENT) {
                data.remove(ChapterResourceViewEnum.PREPARATION_MATERIALS);
            }
            return data;
        }

        @Override
        public List<ResourcesTypeEnum> getResourceType() {
            List<ResourcesTypeEnum> resourcesTypeEnums = ChapterTypeEnum.THEORY.getResourceType();
            resourcesTypeEnums.addAll(ChapterTypeEnum.EXPERIMENT.getResourceType());
            return resourcesTypeEnums.stream().distinct().collect(Collectors.toList());
        }
    };

    private Integer code;

    private String message;

    public abstract List<ChapterResourceViewEnum> getChapterResourceView(IdentityEnum identityEnum);

    public abstract List<ResourcesTypeEnum> getResourceType();

    public static ChapterTypeEnum getByCode(Integer code) {
        for (ChapterTypeEnum chapterTypeEnum : ChapterTypeEnum.values()) {
            if (Objects.equals(chapterTypeEnum.getCode(), code)) {
                return chapterTypeEnum;
            }
        }
        return null;
    }

    public static ChapterTypeEnum getByMessage(String message) {
        for (ChapterTypeEnum chapterTypeEnum : ChapterTypeEnum.values()) {
            if (Objects.equals(chapterTypeEnum.getMessage(), message)) {
                return chapterTypeEnum;
            }
        }
        return null;
    }

    public static String getMessageByCode(Integer code) {
        ChapterTypeEnum chapterTypeEnum = getByCode(code);
        return chapterTypeEnum == null ? null : chapterTypeEnum.getMessage();
    }

    /**
     * 获取理论课类型
     *
     * @return
     */
    public static List<Integer> getTheoryTypes() {
        return Lists.newArrayList(THEORY.code, THEORY_EXPERIMENT.code, THEORY_MANY_EXPERIMENT.code);
    }

    /**
     * 获取实验课类型
     *
     * @return
     */
    public static List<Integer> getExperimentTypes() {
        return Lists.newArrayList(EXPERIMENT.code, THEORY_EXPERIMENT.code, THEORY_MANY_EXPERIMENT.code);
    }

    public static List<Integer> getManyExperiment() {
        return Lists.newArrayList(THEORY_MANY_EXPERIMENT.code);
    }

    /**
     * 是否包含实验
     *
     * @param code
     * @return
     */
    public static boolean isContainsTheory(Integer code) {
        if (getTheoryTypes().contains(code)) {
            return true;
        }
        return false;
    }

    /**
     * 是否包含实验
     *
     * @param code
     * @return
     */
    public static boolean isContainsExperiment(Integer code) {
        if (getExperimentTypes().contains(code)) {
            return true;
        }
        return false;
    }

    public static boolean isContainsSingleExperiment(Integer code) {
        if (Objects.equals(code, THEORY_EXPERIMENT.code) || Objects.equals(code, EXPERIMENT.code)) {
            return true;
        }
        return false;
    }

    /**
     * 是否是多实验课
     *
     * @param code
     * @return
     */
    public static boolean isManyExperiment(Integer code) {
        if (getManyExperiment().contains(code)) {
            return true;
        }
        return false;
    }

}
